home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / networking / amitcp / httpd.lha / httpd / http_config.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-18  |  23.0 KB  |  717 lines

  1. /*
  2.  * http_config.c: auxillary functions for reading httpd's config file
  3.  * and converting filenames into a namespace
  4.  *
  5.  * Rob McCool 
  6.  * 
  7.  */
  8.  
  9. #include "httpd.h"
  10.  
  11.  
  12. /* Server config globals */
  13. int standalone;
  14. int port;
  15. uid_t user_id;
  16. gid_t group_id;
  17. char server_root[MAX_STRING_LEN];
  18. char error_fname[MAX_STRING_LEN];
  19. char xfer_fname[MAX_STRING_LEN];
  20. char pid_fname[MAX_STRING_LEN];
  21. char server_admin[MAX_STRING_LEN];
  22. char *server_hostname;
  23. char srm_confname[MAX_STRING_LEN];
  24. char server_confname[MAX_STRING_LEN];
  25. char access_confname[MAX_STRING_LEN];
  26. char types_confname[MAX_STRING_LEN];
  27. int timeout;
  28.  
  29. void process_server_config() {
  30.     FILE *cfg;
  31.     char l[MAX_STRING_LEN],w[MAX_STRING_LEN];
  32.     int n=0;
  33.  
  34.     standalone = 1;
  35.     port = DEFAULT_PORT;
  36. #ifndef AMIGA
  37.     user_id = uname2id(DEFAULT_USER);
  38. #else
  39.     user_id = 0;
  40. #endif
  41.     group_id = gname2id(DEFAULT_GROUP);
  42.     /* ServerRoot set in httpd.c */
  43.     make_full_path(server_root,DEFAULT_ERRORLOG,error_fname);
  44.     make_full_path(server_root,DEFAULT_XFERLOG,xfer_fname);
  45.     make_full_path(server_root,DEFAULT_PIDLOG,pid_fname);
  46.     strcpy(server_admin,DEFAULT_ADMIN);
  47.     server_hostname = NULL;
  48.     make_full_path(server_root,RESOURCE_CONFIG_FILE,srm_confname);
  49.     /* server_confname set in httpd.c */
  50.     make_full_path(server_root,ACCESS_CONFIG_FILE,access_confname);
  51.     make_full_path(server_root,TYPES_CONFIG_FILE,types_confname);
  52.  
  53.     timeout = DEFAULT_TIMEOUT;
  54.  
  55.     if(!(cfg = fopen(server_confname,"r"))) {
  56.         fprintf(stderr,"httpd: could not open server config. file %s\n",server_confname);
  57.         perror("fopen");
  58.         exit(1);
  59.     }
  60.     /* Parse server config file. Remind me to learn yacc. */
  61.     while(!(cfg_getline(l,MAX_STRING_LEN,cfg))) {
  62.         ++n;
  63.         if((l[0] != '#') && (l[0] != '\0')) {
  64.             cfg_getword(w,l);
  65.             
  66.             if(!strcasecmp(w,"ServerType")) {
  67.                 if(!strcasecmp(l,"inetd")) standalone=0;
  68.                 else if(!strcasecmp(l,"standalone")) standalone=1;
  69.                 else {
  70.                     fprintf(stderr,"Syntax error on line %d of %s:\n",n,server_confname);
  71.                     fprintf(stderr,"ServerType is either inetd or standalone.\n");
  72.                     exit(1);
  73.                 }
  74.             }
  75.             else if(!strcasecmp(w,"Port")) {
  76.                 cfg_getword(w,l);
  77.                 port = atoi(w);
  78.             }
  79.             else if(!strcasecmp(w,"User")) {
  80.                 cfg_getword(w,l);
  81. #ifndef AMIGA
  82.                 user_id = uname2id(w);
  83. #else
  84.         user_id = 0;
  85. #endif
  86.             } 
  87.             else if(!strcasecmp(w,"Group")) {
  88.                 cfg_getword(w,l);
  89.                 group_id = gname2id(w);
  90.             }
  91.             else if(!strcasecmp(w,"ServerAdmin")) {
  92.                 cfg_getword(w,l);
  93.                 strcpy(server_admin,w);
  94.             }
  95.             else if(!strcasecmp(w,"ServerName")) {
  96.                 cfg_getword(w,l);
  97.                 server_hostname = strdup(w);
  98.             }
  99.             else if(!strcasecmp(w,"ServerRoot")) {
  100.                 cfg_getword(w,l);
  101.                 if(!is_directory(w)) {
  102.                     fprintf(stderr,"Syntax error on line %d of %s:\n",n,server_confname);
  103.                     fprintf(stderr,"%s is not a valid directory.\n",w);
  104.                     exit(1);
  105.                 }
  106.                 strcpy(server_root,w);
  107.           make_full_path(server_root,DEFAULT_ERRORLOG,error_fname);
  108.           make_full_path(server_root,DEFAULT_XFERLOG,xfer_fname);
  109.           make_full_path(server_root,DEFAULT_PIDLOG,pid_fname);
  110.           make_full_path(server_root,RESOURCE_CONFIG_FILE,srm_confname);
  111.           make_full_path(server_root,ACCESS_CONFIG_FILE,access_confname);
  112.           make_full_path(server_root,TYPES_CONFIG_FILE,types_confname);
  113.             }
  114.             else if(!strcasecmp(w,"ErrorLog")) {
  115.                 cfg_getword(w,l);
  116.                 if(w[0] != '/')
  117.                     make_full_path(server_root,w,error_fname);
  118.                 else 
  119.                     strcpy(error_fname,w);
  120.             } 
  121.             else if(!strcasecmp(w,"TransferLog")) {
  122.                 cfg_getword(w,l);
  123.                 if(w[0] != '/')
  124.                     make_full_path(server_root,w,xfer_fname);
  125.                 else strcpy(xfer_fname,w);
  126.             }
  127.             else if(!strcasecmp(w,"PidFile")) {
  128.                 cfg_getword(w,l);
  129.                 if(w[0] != '/')
  130.                     make_full_path(server_root,w,pid_fname);
  131.                 else strcpy(pid_fname,w);
  132.             }
  133.             else if(!strcasecmp(w,"AccessConfig")) {
  134.                 cfg_getword(w,l);
  135.                 if(w[0] != '/')
  136.                     make_full_path(server_root,w,access_confname);
  137.                 else strcpy(access_confname,w);
  138.             }
  139.             else if(!strcasecmp(w,"ResourceConfig")) {
  140.                 cfg_getword(w,l);
  141.                 if(w[0] != '/')
  142.                     make_full_path(server_root,w,srm_confname);
  143.                 else strcpy(srm_confname,w);
  144.             }
  145.             else if(!strcasecmp(w,"TypesConfig")) {
  146.                 cfg_getword(w,l);
  147.                 if(w[0] != '/')
  148.                     make_full_path(server_root,w,types_confname);
  149.                 else strcpy(types_confname,w);
  150.             }
  151.             else if(!strcasecmp(w,"Timeout"))
  152.                 timeout = atoi(l);
  153.             else {
  154.                 fprintf(stderr,"Syntax error on line %d of %s:\n",n,server_confname);
  155.                 fprintf(stderr,"Unknown keyword %s.\n",w);
  156.                 exit(1);
  157.             }
  158.         }
  159.     }
  160.     fclose(cfg);
  161. }
  162.  
  163.  
  164.  
  165. /* Document config globals */
  166. char user_dir[MAX_STRING_LEN];
  167. char index_name[MAX_STRING_LEN];
  168. char access_name[MAX_STRING_LEN];
  169. char document_root[MAX_STRING_LEN];
  170. char default_type[MAX_STRING_LEN];
  171.  
  172. void process_resource_config() {
  173.     FILE *cfg;
  174.     char l[MAX_STRING_LEN],w[MAX_STRING_LEN];
  175.     int n=0;
  176.  
  177.     strcpy(user_dir,DEFAULT_USER_DIR);
  178.     strcpy(index_name,DEFAULT_INDEX);
  179.     strcpy(access_name,DEFAULT_ACCESS_FNAME);
  180.     strcpy(document_root,DOCUMENT_LOCATION);
  181.     strcpy(default_type,DEFAULT_TYPE);
  182.  
  183.     if(!(cfg = fopen(srm_confname,"r"))) {
  184.         fprintf(stderr,"httpd: could not open document config. file %s\n",
  185.                 srm_confname);
  186.         perror("fopen");
  187.         exit(1);
  188.     }
  189.  
  190.     while(!(cfg_getline(l,MAX_STRING_LEN,cfg))) {
  191.         ++n;
  192.         if((l[0] != '#') && (l[0] != '\0')) {
  193.             cfg_getword(w,l);
  194.             
  195.             if(!strcasecmp(w,"ScriptAlias")) {
  196.                 char w2[MAX_STRING_LEN];
  197.             
  198.                 cfg_getword(w,l);
  199.                 cfg_getword(w2,l);
  200.                 if((w[0] == '\0') || (w2[0] == '\0')) {
  201.                     fprintf(stderr,"Syntax error on line %d of %s:\n",n,
  202.                             srm_confname);
  203.                     fprintf(stderr,
  204. "ScriptAlias must be followed by a fakename, one space, then a realname.\n");
  205.                     exit(1);
  206.                 }                
  207.                 add_alias(w,w2,SCRIPT_CGI);
  208.             }
  209.             if(!strcasecmp(w,"OldScriptAlias")) {
  210.                 char w2[MAX_STRING_LEN];
  211.             
  212.                 cfg_getword(w,l);
  213.                 cfg_getword(w2,l);
  214.                 if((w[0] == '\0') || (w2[0] == '\0')) {
  215.                     fprintf(stderr,"Syntax error on line %d of %s:\n",n,
  216.                             srm_confname);
  217.                     fprintf(stderr,
  218. "ScriptAlias must be followed by a fakename, one space, then a realname.\n");
  219.                     exit(1);
  220.                 }                
  221.                 add_alias(w,w2,SCRIPT_NCSA);
  222.             }
  223.             else if(!strcasecmp(w,"UserDir")) {
  224.                 cfg_getword(w,l);
  225.                 if(!strcmp(w,"DISABLED"))
  226.                     user_dir[0] = '\0';
  227.                 else
  228.                     strcpy(user_dir,w);
  229.             }
  230.             else if(!strcasecmp(w,"DirectoryIndex")) {
  231.                 cfg_getword(w,l);
  232.                 strcpy(index_name,w);
  233.             } 
  234.             else if(!strcasecmp(w,"DefaultType")) {
  235.                 cfg_getword(w,l);
  236.                 strcpy(default_type,w);
  237.             }
  238.             else if(!strcasecmp(w,"AccessFileName")) {
  239.                 cfg_getword(w,l);
  240.                 strcpy(access_name,w);
  241.             } 
  242.             else if(!strcasecmp(w,"DocumentRoot")) {
  243.                 cfg_getword(w,l);
  244.                 if(!is_directory(w)) {
  245.                     fprintf(stderr,"Syntax error on line %d of %s:\n",n,
  246.                             srm_confname);
  247.                     fprintf(stderr,"%s is not a valid directory.\n",w);
  248.                     exit(1);
  249.                 }
  250.                 strcpy(document_root,w);
  251.             } 
  252.             else if(!strcasecmp(w,"Alias")) {
  253.                 char w2[MAX_STRING_LEN];
  254.         
  255.                 cfg_getword(w,l);
  256.                 cfg_getword(w2,l);
  257.                 if((w[0] == '\0') || (w2[0] == '\0')) {
  258.                     fprintf(stderr,"Syntax error on line %d of %s:\n",n,
  259.                             srm_confname);
  260.                     fprintf(stderr,
  261. "Alias must be followed by a fakename, one space, then a realname.\n");
  262.                     exit(1);
  263.                 }                
  264.                 add_alias(w,w2,STD_DOCUMENT);
  265.             }
  266.             else if(!strcasecmp(w,"AddType")) {
  267.                 char w2[MAX_STRING_LEN];
  268.                 cfg_getword(w,l);
  269.                 cfg_getword(w2,l);
  270.                 if((w[0] == '\0') || (w2[0] == '\0')) {
  271.                     fprintf(stderr,"Syntax error on line %d of %s:\n",n,
  272.                             srm_confname);
  273.                     fprintf(stderr,
  274. "AddType must be followed by a type, one space, then a file or extension.\n");
  275.                     exit(1);
  276.                 }
  277.                 add_type(w2,w);
  278.             }
  279.             else if(!strcasecmp(w,"AddEncoding")) {
  280.                 char w2[MAX_STRING_LEN];
  281.                 cfg_getword(w,l);
  282.                 cfg_getword(w2,l);
  283.                 if((w[0] == '\0') || (w2[0] == '\0')) {
  284.                     fprintf(stderr,"Syntax error on line %d of %s:\n",n,
  285.                             srm_confname);
  286.                     fprintf(stderr,
  287. "AddEncoding must be followed by a type, one space, then a file or extension.\n");
  288.                     exit(1);
  289.                 }
  290.                 add_encoding(w2,w);
  291.             }
  292.             else if(!strcasecmp(w,"Redirect")) {
  293.                 char w2[MAX_STRING_LEN];
  294.                 cfg_getword(w,l);
  295.                 cfg_getword(w2,l);
  296.                 if((w[0] == '\0') || (w2[0] == '\0') || (!is_url(w2))) {
  297.                     fprintf(stderr,"Syntax error on line %d of %s:\n",n,
  298.                             srm_confname);
  299.                     fprintf(stderr,
  300. "Redirect must be followed by a document, one space, then a URL.\n");
  301.                     exit(1);
  302.                 }
  303.                 add_redirect(w,w2);
  304.             }
  305.         }
  306.     }
  307.     fclose(cfg);
  308. }
  309.  
  310.  
  311. /* Auth Globals */
  312. char *auth_type;
  313. char *auth_name;
  314. char *auth_pwfile;
  315. char *auth_grpfile;
  316.  
  317. /* Access Globals*/
  318. int num_sec;
  319. #ifndef AMIGA
  320. security_data sec[MAX_SECURITY];
  321. #else
  322. security_data __far sec[MAX_SECURITY];
  323. #endif
  324.  
  325. void access_syntax_error(int n, char *err, char *file) {
  326.     if(!file) {
  327.         fprintf(stderr,"Syntax error on line %d of access config. file.\n",n);
  328.         fprintf(stderr,"%s\n",err);
  329.         exit(1);
  330.     }
  331.     else {
  332.         char e[MAX_STRING_LEN];
  333.         sprintf(e,"httpd: syntax error or override violation in access control file %s, reason: %s",file,err);
  334.         die(SERVER_ERROR,e,stdout); /* AAAAAGH STDOUT */
  335.     }
  336. }
  337.  
  338. int parse_access_dir(FILE *f, int line, char or, char *dir, char *file) 
  339. {
  340.     char l[MAX_STRING_LEN];
  341.     char t[MAX_STRING_LEN];
  342.     char w[MAX_STRING_LEN];
  343.     char w2[MAX_STRING_LEN];
  344.     int n=line;
  345.     register int x,i;
  346.  
  347.     x = num_sec;
  348.  
  349.     sec[x].opts=OPT_ALL;
  350.     sec[x].override = or;
  351.     sec[x].d = (char *)malloc((sizeof(char)) * (strlen(dir) + 2));
  352.     strcpy_dir(sec[x].d,dir);
  353.     sec[x].auth_type = NULL;
  354.     sec[x].auth_name = NULL;
  355.     sec[x].auth_pwfile = NULL;
  356.     sec[x].auth_grpfile = NULL;
  357.     for(i=0;i<METHODS;i++) {
  358.         sec[x].order[i] = DENY_THEN_ALLOW;
  359.         sec[x].num_allow[i]=0;
  360.         sec[x].num_deny[i]=0;
  361.         sec[x].num_auth[i] = 0;
  362.     }
  363.  
  364.     while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
  365.         ++n;
  366.         if((l[0] == '#') || (!l[0])) continue;
  367.         cfg_getword(w,l);
  368.  
  369.         if(!strcasecmp(w,"AllowOverride")) {
  370.             if(file)
  371.                 access_syntax_error(n,"override violation",file);
  372.             sec[x].override = OR_NONE;
  373.             while(l[0]) {
  374.                 cfg_getword(w,l);
  375.                 if(!strcasecmp(w,"Limit"))
  376.                     sec[x].override |= OR_LIMIT;
  377.                 else if(!strcasecmp(w,"Options"))
  378.                     sec[x].override |= OR_OPTIONS;
  379.                 else if(!strcasecmp(w,"FileInfo"))
  380.                     sec[x].override |= OR_FILEINFO;
  381.                 else if(!strcasecmp(w,"AuthConfig"))
  382.                     sec[x].override |= OR_AUTHCFG;
  383.                 else if(!strcasecmp(w,"None"))
  384.                     sec[x].override = OR_NONE;
  385.                 else if(!strcasecmp(w,"All")) 
  386.                     sec[x].override = OR_ALL;
  387.                 else {
  388.                     access_syntax_error(n,
  389. "Unknown keyword in AllowOverride directive.",file);
  390.                 }
  391.             }
  392.         } 
  393.         else if(!strcasecmp(w,"Options")) {
  394.             if(!(or & OR_OPTIONS))
  395.                 access_syntax_error(n,"override violation",file);
  396.             sec[x].opts = OPT_NONE;
  397.             while(l[0]) {
  398.                 cfg_getword(w,l);
  399.                 if(!strcasecmp(w,"Indexes"))
  400.                     sec[x].opts |= OPT_INDEXES;
  401.                 else if(!strcasecmp(w,"Includes"))
  402.                     sec[x].opts |= OPT_INCLUDES;
  403.                 else if(!strcasecmp(w,"FollowSymLinks"))
  404.                     sec[x].opts |= OPT_SYM_LINKS;
  405.                 else if(!strcasecmp(w,"None")) 
  406.                     sec[x].opts = OPT_NONE;
  407.                 else if(!strcasecmp(w,"All")) 
  408.                     sec[x].opts = OPT_ALL;
  409.                 else {
  410.                     access_syntax_error(n,
  411. "Unknown keyword in Options directive.",file);
  412.                 }
  413.             }
  414.         }
  415.         else if(!strcasecmp(w,"AuthName")) {
  416.             if(!(or & OR_AUTHCFG))
  417.                 access_syntax_error(n,"override violation",file);
  418.             if(sec[x].auth_name) 
  419.                 free(sec[x].auth_name);
  420.             sec[x].auth_name = strdup(l);
  421.         }
  422.         else if(!strcasecmp(w,"AuthType")) {
  423.             if(!(or & OR_AUTHCFG))
  424.                 access_syntax_error(n,"override violation",file);
  425.             cfg_getword(w,l);
  426.             if(sec[x].auth_type) 
  427.                 free(sec[x].auth_type);
  428.             sec[x].auth_type = strdup(w);
  429.         }
  430.         else if(!strcasecmp(w,"AuthUserFile")) {
  431.             if(!(or & OR_AUTHCFG))
  432.                 access_syntax_error(n,"override violation",file);
  433.             cfg_getword(w,l);
  434.             if(sec[x].auth_pwfile) 
  435.                 free(sec[x].auth_pwfile);
  436.             sec[x].auth_pwfile = strdup(w);
  437.         }
  438.         else if(!strcasecmp(w,"AuthGroupFile")) {
  439.             if(!(or & OR_AUTHCFG))
  440.                 access_syntax_error(n,"override violation",file);
  441.             cfg_getword(w,l);
  442.             if(sec[x].auth_grpfile) 
  443.                 free(sec[x].auth_grpfile);
  444.             sec[x].auth_grpfile = strdup(w);
  445.         }
  446.         else if(!strcasecmp(w,"AddType")) {
  447.             if(!(or & OR_FILEINFO))
  448.                 access_syntax_error(n,"override violation",file);
  449.             cfg_getword(w,l);
  450.             cfg_getword(w2,l);
  451.             if((w[0] == '\0') || (w2[0] == '\0')) {
  452.                 access_syntax_error(n,
  453. "AddType must be followed by a type, one space, then a file or extension.",
  454.                                     file);
  455.             }
  456.             add_type(w2,w);
  457.         }
  458.         else if(!strcasecmp(w,"AddEncoding")) {
  459.             if(!(or & OR_FILEINFO))
  460.                 access_syntax_error(n,"override violation",file);
  461.             cfg_getword(w,l);
  462.             cfg_getword(w2,l);
  463.             if((w[0] == '\0') || (w2[0] == '\0')) {
  464.                 access_syntax_error(n,
  465. "AddEncoding must be followed by a type, one space, then a file or extension.",
  466.                                     file);
  467.             }
  468.             add_encoding(w2,w);
  469.         }
  470.         else if(!strcasecmp(w,"Redirect")) {
  471.             if(!(or & OR_FILEINFO))
  472.                 access_syntax_error(n,"override violation",file);
  473.             cfg_getword(w,l);
  474.             cfg_getword(w2,l);
  475.             if((w[0] == '\0') || (w2[0] == '\0') || (!is_url(w2))) {
  476.                 access_syntax_error(n,
  477. "Redirect must be followed by a document, one space, then a URL.",file);
  478.             }
  479.             if(!file)
  480.                 add_redirect(w,w2);
  481.             else
  482.                 access_syntax_error(n,
  483. "Redirect no longer supported from .htaccess files.",file);
  484.         }
  485.         else if(!strcasecmp(w,"<Limit")) {
  486.             int m[METHODS];
  487.  
  488.             if(!(or & OR_LIMIT))
  489.                 access_syntax_error(n,"override violation",file);
  490.             for(i=0;i<METHODS;i++) m[i] = 0;
  491.             getword(w2,l,'>');
  492.             while(w2[0]) {
  493.                 cfg_getword(w,w2);
  494.                 if(!strcasecmp(w,"GET")) m[M_GET]=1;
  495.                 else if(!strcasecmp(w,"PUT")) m[M_PUT]=1;
  496.                 else if(!strcasecmp(w,"POST")) m[M_POST]=1;
  497.             }
  498.             while(1) {
  499.                 if(cfg_getline(l,MAX_STRING_LEN,f))
  500.                     access_syntax_error(n,"Limit missing /Limit",file);
  501.                 n++;
  502.                 if((l[0] == '#') || (!l[0])) continue;
  503.  
  504.                 if(!strcasecmp(l,"</Limit>"))
  505.                     break;
  506.                 cfg_getword(w,l);
  507.                 if(!strcasecmp(w,"order")) {
  508.                     if(!strcasecmp(l,"allow,deny")) {
  509.                         for(i=0;i<METHODS;i++)
  510.                             if(m[i])
  511.                                 sec[x].order[i] = ALLOW_THEN_DENY;
  512.                     }
  513.                     else if(!strcasecmp(l,"deny,allow")) {
  514.                         for(i=0;i<METHODS;i++)
  515.                             if(m[i]) 
  516.                                 sec[x].order[i] = DENY_THEN_ALLOW;
  517.                     }
  518.                     else
  519.                         access_syntax_error(n,"Unknown order.",file);
  520.                 } 
  521.                 else if((!strcasecmp(w,"allow"))) {
  522.                     cfg_getword(w,l);
  523.                     if(strcmp(w,"from"))
  524.                         access_syntax_error(n,
  525.                                             "allow must be followed by from.",
  526.                                             file);
  527.                     while(1) {
  528.                         cfg_getword(w,l);
  529.                         if(!w[0]) break;
  530.                         for(i=0;i<METHODS;i++)
  531.                             if(m[i]) {
  532.                                 int q=sec[x].num_allow[i]++;
  533.                                     sec[x].allow[i][q] = strdup(w);
  534.                                 }
  535.                     }
  536.                 }
  537.                 else if(!strcasecmp(w,"require")) {
  538.                     for(i=0;i<METHODS;i++)
  539.                         if(m[i]) {
  540.                             int q=sec[x].num_auth[i]++;
  541.                             sec[x].auth[i][q] = strdup(l);
  542.                         }
  543.                 }
  544.                 else if((!strcasecmp(w,"deny"))) {
  545.                     cfg_getword(w,l);
  546.                     if(strcmp(w,"from"))
  547.                         access_syntax_error(n,
  548.                                             "deny must be followed by from.",
  549.                                             file);
  550.                     while(1) {
  551.                         cfg_getword(w,l);
  552.                         if(!w[0]) break;
  553.                         for(i=0;i<METHODS;i++)
  554.                             if(m[i]) {
  555.                                 int q=sec[x].num_deny[i]++;
  556.                                 sec[x].deny[i][q] = strdup(w);
  557.                             }
  558.                     }
  559.                 }
  560.                 else
  561.                     access_syntax_error(n,"Unknown keyword in Limit region.",
  562.                                         file);
  563.             }
  564.         }
  565.         else if(!strcasecmp(w,"</Directory>"))
  566.             break;
  567.         else {
  568.             char errstr[MAX_STRING_LEN];
  569.             sprintf(errstr,"Unknown method %s",w);
  570.             access_syntax_error(n,errstr,file);
  571.             return;
  572.         }
  573.     }
  574.     ++num_sec;
  575.     return n;
  576. }
  577.  
  578.  
  579. void parse_htaccess(char *path, char override) {
  580.     FILE *f;
  581.     char t[MAX_STRING_LEN];
  582.     char d[MAX_STRING_LEN];
  583.     int x;
  584.  
  585.     strcpy(d,path);
  586.     make_full_path(d,access_name,t);
  587.  
  588.     if((f=fopen(t,"r"))) {
  589.         parse_access_dir(f,-1,override,d,t);
  590.         fclose(f);
  591.     }
  592. }
  593.  
  594.  
  595. void process_access_config() {
  596.     FILE *f;
  597.     char l[MAX_STRING_LEN];
  598.     char w[MAX_STRING_LEN];
  599.     int n;
  600.  
  601.     num_sec = 0;n=0;
  602.     if(!(f=fopen(access_confname,"r"))) {
  603.         fprintf(stderr,"httpd: could not open access configuration file %s.\n",
  604.                 access_confname);
  605.         perror("fopen");
  606.         exit(1);
  607.     }
  608.     while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
  609.         ++n;
  610.         if((l[0] == '#') || (!l[0])) continue;
  611.         cfg_getword(w,l);
  612.         if(strcasecmp(w,"<Directory")) {
  613.             fprintf(stderr,
  614.                     "Syntax error on line %d of access config. file.\n",n);
  615.             fprintf(stderr,"Unknown directive %s.\n",w);
  616.             exit(1);
  617.         }
  618.         getword(w,l,'>');
  619.         n=parse_access_dir(f,n,OR_ALL,w,NULL);
  620.     }
  621.     fclose(f);
  622. }
  623.  
  624. int get_pw(char *user, char *pw) {
  625.     FILE *f;
  626.     char errstr[MAX_STRING_LEN];
  627.     char l[MAX_STRING_LEN];
  628.     char w[MAX_STRING_LEN];
  629.  
  630.     if(!(f=fopen(auth_pwfile,"r"))) {
  631.         sprintf(errstr,"Could not open user file %s",auth_pwfile);
  632.         die(SERVER_ERROR,errstr,stdout); /* AAAAAAAAGH stdout */
  633.     }
  634.     while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
  635.         if((l[0] == '#') || (!l[0])) continue;
  636.         getword(w,l,':');
  637.  
  638.         if(!strcmp(user,w)) {
  639.             strcpy(pw,l);
  640.             fclose(f);
  641.             return 1;
  642.         }
  643.     }
  644.     fclose(f);
  645.     return 0;
  646. }
  647.  
  648.  
  649. struct ge {
  650.     char *name;
  651.     char *members;
  652.     struct ge *next;
  653. };
  654.  
  655. static struct ge *grps;
  656.  
  657. int init_group(char *grpfile) {
  658.     FILE *f;
  659.     struct ge *p;
  660.     char l[MAX_STRING_LEN],w[MAX_STRING_LEN];
  661.  
  662.     if(!(f=fopen(grpfile,"r")))
  663.         return 0;
  664.  
  665.     grps = NULL;
  666.     while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
  667.         if((l[0] == '#') || (!l[0])) continue;
  668.         getword(w,l,':');
  669.         p = (struct ge *) malloc (sizeof(struct ge));
  670.         p->name = strdup(w);
  671.         p->members = strdup(l);
  672.         p->next = grps;
  673.         grps = p;
  674.     }
  675.     fclose(f);
  676.     return 1;
  677. }
  678.  
  679. int in_group(char *user, char *group) {
  680.     struct ge *p = grps;
  681.     char l[MAX_STRING_LEN],w[MAX_STRING_LEN];
  682.  
  683.     while(p) {
  684.         if(!strcmp(p->name,group)) {
  685.             strcpy(l,p->members);
  686.             while(l[0]) {
  687.                 getword(w,l,' ');
  688.                 if(!strcmp(w,user))
  689.                     return 1;
  690.             }
  691.         }
  692.         p=p->next;
  693.     }
  694.     return 0;
  695. }
  696.  
  697. void kill_group() {
  698.     struct ge *p = grps, *q;
  699.  
  700.     while(p) {
  701.         free(p->name);
  702.         free(p->members);
  703.         q=p;
  704.         p=p->next;
  705.         free(q);
  706.     }   
  707. }
  708.  
  709. void read_config()
  710. {
  711.     reset_aliases();
  712.     process_server_config();
  713.     init_mime();
  714.     process_resource_config();
  715.     process_access_config();
  716. }
  717.